/* -*-jde-*- */
package app.alumnoe;

import app.conexion.Conexion;
import app.conexion.ConexionException;
import app.empresa.Vacante;
import app.htmlGenerator.HTMLVacanteGenerator;
import app.util.Fecha;
import app.util.SQLInjectionException;
import app.util.Validator;
import app.util.appException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Bean Vacante Genera una Vacante para la empresa dependiendo del identificador
 * de usuario
 *
 * @author Victor Miguel Peralta Santa Anna
 * @since Enero 2012
 * @version 0.1
 */
public class Busqueda {

    /**
     * Limitamos el uso de la clase de búsqueda
     */
    private Busqueda() {
    }

    /**
     * Método que regresa la lista de TODAS las vacantes dadas por una cadena de
     * búsqueda
     *
     * @throws appException
     */
    public static LinkedList<Vacante> buscaVacantesCon(String busqueda) throws appException {
        try {

            Conexion con = new Conexion();
            LinkedList<Vacante> vacantes = new LinkedList<Vacante>();

            if (!Validator.checkSQLInjection(busqueda)) {

                String query = "SELECT * FROM Vacantes  WHERE bactivado = TRUE AND sDescripcion"
                        + " LIKE '%" + busqueda + "%' OR  sTituloVacante LIKE '%" + busqueda
                        + "%' OR srequisitos LIKE '% " + busqueda + "%';";
                //String query = "SELECT * FROM Vacantes  WHERE bactivado = TRUE AND sDescripcion" + " ~('" + busqueda + "') OR  sTituloVacante ~('" + busqueda + "');";
                //String query = "SELECT * FROM buscaVacantesGIN(' " + busqueda + "') ;";

                ResultSet r = con.exec(query);

                while (r.next()) {
                    int id1 = r.getInt("nidvacante");
                    String s1 = r.getString("stitulovacante");
                    String s2 = r.getString("sdescripcion");
                    String s3 = r.getString("sprofesionalesbuscados");
                    String s4 = r.getString("srequisitos");
                    String s5 = r.getString("sofrecen");
                    Fecha s6 = new Fecha(r.getString("dfechapublicacion"));
                    String s7 = r.getString("sinformacion");
                    String s8 = r.getString("snombrecompletocontacto");
                    String s9 = r.getString("scorreo");
                    String s10 = r.getString("stelefono");
                    double s11 = r.getDouble("nlatitud");
                    double s12 = r.getDouble("nlongitud");
                    boolean s13 = r.getBoolean("bbeca");
                    boolean s14 = r.getBoolean("bpracticasprofesionales");
                    boolean s15 = r.getBoolean("bactivado");

                    String queryEmp = "select * from empresavacantes where nidvacante = " + id1;
                    ResultSet r1 = con.exec(queryEmp);
                    r1.next();
                    int idemp = r1.getInt("nidusuario");

                    Vacante v = new Vacante(id1, idemp, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
                    HTMLVacanteGenerator htmlvg = new HTMLVacanteGenerator(v);
                    String html = htmlvg.generarVacante();

                    v.setHtmlVacante(html);
                    vacantes.add(v);
                }

            }

            con.close();

            return vacantes;

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pueden recuperar las vacantes de la base de datos");
        } catch (ConexionException ex) {
            System.err.println(ex);
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pueden recuperar las vacantes de la base de datos");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    /**
     * Método que regresa la lista de TODAS las vacantes dadas por una cadena de
     * búsqueda
     *
     * @throws appException
     */
    public static LinkedList<Vacante> buscaVacantesConA(String busqueda, double latitud, double longitud, double distancia) throws appException {
        try {

            Conexion con = new Conexion();
            LinkedList<Vacante> vacantes = new LinkedList<Vacante>();
            LinkedList<Vacante> vacanteDifer = new LinkedList<Vacante>();

            if (!Validator.checkSQLInjection(busqueda)) {

                String query = "SELECT * FROM Vacantes  WHERE bactivado = TRUE AND sDescripcion"
                        + " LIKE '%" + busqueda + "%' OR  sTituloVacante LIKE '%" + busqueda
                        + "%' OR srequisitos LIKE '% " + busqueda + "%';";
                //String query = "SELECT * FROM Vacantes  WHERE bactivado = TRUE AND sDescripcion" + " ~('" + busqueda + "') OR  sTituloVacante ~('" + busqueda + "');";
                //String query = "SELECT * FROM buscaVacantesGIN(' " + busqueda + "') ;";

                ResultSet r = con.exec(query);

                while (r.next()) {
                    int id1 = r.getInt("nidvacante");
                    String s1 = r.getString("stitulovacante");
                    String s2 = r.getString("sdescripcion");
                    String s3 = r.getString("sprofesionalesbuscados");
                    String s4 = r.getString("srequisitos");
                    String s5 = r.getString("sofrecen");
                    Fecha s6 = new Fecha(r.getString("dfechapublicacion"));
                    String s7 = r.getString("sinformacion");
                    String s8 = r.getString("snombrecompletocontacto");
                    String s9 = r.getString("scorreo");
                    String s10 = r.getString("stelefono");
                    double s11 = r.getDouble("nlatitud");
                    double s12 = r.getDouble("nlongitud");
                    boolean s13 = r.getBoolean("bbeca");
                    boolean s14 = r.getBoolean("bpracticasprofesionales");
                    boolean s15 = r.getBoolean("bactivado");

                    String queryEmp = "select * from empresavacantes where nidvacante = " + id1;
                    ResultSet r1 = con.exec(queryEmp);
                    r1.next();
                    int idemp = r1.getInt("nidusuario");

                    Vacante v = new Vacante(id1, idemp, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15);
                    HTMLVacanteGenerator htmlvg = new HTMLVacanteGenerator(v);
                    String html = htmlvg.generarVacante();

                    v.setHtmlVacante(html);
                    vacantes.add(v);
                }


                //LatLng centro = new LatLng(latitud, longitud);



                for (Vacante v : vacantes) {

                    // Sacamos la distancia de dos puntos en el globo.
                    double latitud2 = v.getLatitud();
                    double longitud2 = v.getLongitud();

                    double distKM = haversineKm(latitud, longitud, latitud2, longitud2);



                    // Colocamos las vacantes de menor distancia dentro de la nueva lista y la regresamos
                    if (distKM <= distancia) {
                        v.setDistanciaMax(distKM);
                        vacanteDifer.add(v);
                    }

                    System.out.println("Latitud: " + latitud);
                    System.out.println("Longitud: " + longitud);

                    System.out.println("Latituds: " + latitud2);
                    System.out.println("Longitud2: " + longitud2);
                    System.out.println("Distancia km : " + distKM);
                }

            }

            con.close();

            return vacanteDifer;

        } catch (SQLException ex) {
            System.err.println(ex);
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pueden recuperar las vacantes de la base de datos");
        } catch (ConexionException ex) {
            System.err.println(ex);
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
            throw new appException("No se pueden recuperar las vacantes de la base de datos");
        } catch (SQLInjectionException sqlie) {
            System.err.println(sqlie);
            Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, sqlie);
            throw new appException(sqlie.getMessage());
        }

    }

    private static double haversineKm(double lat1, double long1, double lat2, double long2) {
        double d2r = Math.PI / 180;
        double dlong = (long2 - long1) * d2r;

        double dlat = (lat2 - lat1) * d2r;
        double a = pow(sin(dlat / 2.0), 2) + cos(lat1 * d2r) * cos(lat2 * d2r) * pow(sin(dlong / 2.0), 2);
        double c = 2 * atan2(sqrt(a), sqrt(1 - a));
        double d = 6367 * c;

        return d;
    }

    private static double pow(double a, int b) {

        return Math.pow(a, b);
    }

    private static double sin(double a) {
        return Math.sin(a);
    }

    private static double cos(double a) {
        return Math.cos(a);
    }

    private static double sqrt(double a) {
        return Math.sqrt(a);
    }

    private static double atan2(double a, double b) {
        return Math.atan2(a, b);
    }

    /**
     * Pruebas de busqueda en la base
     *
     * @param args
     */
    public static void main(String args[]) {
        try {


            LinkedList<Vacante> vacantes = buscaVacantesCon("titulo");

            System.out.println(vacantes);

            for (Vacante v : vacantes) {
                System.out.println(">>>>>>>>>>>>>>>>>>>>>>> \n" + v.getHtmlVacante());
            }


        } catch (appException ex) {
            Logger.getLogger(Busqueda.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
